package com.xiyang.cjtool.cj.support;

import com.xiyang.cjtool.cj.annotation.FXMLController;
import com.xiyang.cjtool.cj.core.AbstractFXMLController;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Parent;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;

/**
 * @author xiyang.ycj
 * @since Sep 10, 2020 14:51:19 PM
 */
public class FXMLConverter {

    private final FXMLController annotation;
    private final URL resource;
    private final Optional<ResourceBundle> bundle;
    private final FXMLLoader loader;

    public FXMLConverter(FXMLController annotation, URL resource, FXMLLoader loader) {
        this.annotation = annotation;
        this.resource = resource;
        this.loader = loader;
    }

    /**
     * cn：从继承类获取{@link FXMLController}注解。
     * en：Gets the {@link FXMLController} annotation from inheriting class.
     * @return the FXML annotation
     */
    public FXMLController getFXMLAnnotation(Class<? extends AbstractFXMLController> clazz) {
        return clazz.getAnnotation(FXMLController.class);
    }

    /**
     * cn：获取URL资源。这将从 应用的注释值获取 或者 根据命名转换。
     * en：Gets the URL resource. This will be derived from applied annotation value
     * or from naming convert.
     *
     * @param annotation the annotation as defined by inheriting class.
     * @return the URL resource
     */
    public URL getURLResource(final FXMLController annotation,Class<? extends AbstractFXMLController> clazz) {
        if (annotation != null && !annotation.view().equals("")) {
            return clazz.getResource("/"+annotation.view());
        } else {
            return clazz.getResource(getFxmlPath());
        }
    }

    /**
     * cn：获取视图fxml的的地址
     * en：Gets the fxml file path.
     *
     * @return 从fxml视图派生的fxml文件的相对路径。.
     *         e.g. AirhacksView 的视图名字是 <PATH>/airhacks.fxml.
     */

    final String getFxmlPath() {
//        final String fxmlPath = fxmlRoot + getConventionalName(".fxml");
//        LOGGER.debug("Determined fxmlPath: " + fxmlPath);
        return "";
    }


    /**
     * 通过加载FXML初始化视图（如果还没有发生），并返回在FXML文件中指定的顶层节点（父节点）。
     *
     * @return the root view as determined from {@link FXMLLoader}.
     */
    public Parent getView(FXMLLoader fxmlLoader) {
        ensureFxmlLoaderInitialized(fxmlLoader);
        return fxmlLoader.getRoot();
    }

    /**
     * Ensure fxml loader initialized.
     */
    private void ensureFxmlLoaderInitialized(FXMLLoader fxmlLoader) {

        if (fxmlLoader != null) {
            return;
        }
        fxmlLoader = loadSynchronously(resource, bundle);

    }

    /**
     * 同步加载 FXMLLoader.
     *
     * @param resource
     *            the resource
     * @param bundle
     *            the bundle
     * @return the FXML loader
     * @throws IllegalStateException
     *             the illegal state exception
     */
    private FXMLLoader loadSynchronously(final URL resource, final Optional<ResourceBundle> bundle) throws IllegalStateException {

        final FXMLLoader loader = new FXMLLoader(resource, bundle.orElse(null));
//        loader.setControllerFactory(this::createControllerForType);
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        try {
            loader.load();
        } catch (final IOException | IllegalStateException e) {
            throw new IllegalStateException("Cannot load ", e);
        }

        return loader;
    }


}
